package com.lu.component.rpc.utils;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.bytecode.*;

import java.lang.reflect.Method;

/**
 * javassist工具类
 *
 * @author: zhanglu
 * @date: 2023/9/4 17:14
 * @modify: 修改人信息, 修改内容 2023/9/4 17:14
 */
public class JavassistUtil {

    /**
     * 通过类名 方法名获取方法中的参数名
     *
     * @param method 方法
     * @return
     */
    public static String[] getMethodParams(Method method) throws Exception {
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get(method.getDeclaringClass().getName());
        CtMethod cm = cc.getDeclaredMethod(method.getName());
        MethodInfo methodInfo = cm.getMethodInfo();
        if (cc.isInterface()) {
            //获取参数的个数
            String[] paramNames = new String[cm.getParameterTypes().length];
            MethodParametersAttribute methodParameters = (MethodParametersAttribute) methodInfo.getAttribute(MethodParametersAttribute.tag);
            for (int i = 0; i < paramNames.length; i++) {
                paramNames[i] = methodParameters.getConstPool().getUtf8Info(ByteArray.readU16bit(methodParameters.get(), i * 4 + 1));
            }
            return paramNames;
        } else {
            CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
            String[] paramNames = new String[cm.getParameterTypes().length];
            LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
            if (attr != null) {
                int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
                for (int i = 0; i < paramNames.length; i++) {
                    paramNames[i] = attr.variableName(i + pos);
                }
            }
            return paramNames;
        }
    }

}
